//
// Created by liaohailong on 2025/4/11.
//

#include "HelloNetworkFetcher.hpp"

HelloNetworkFetcher::HelloNetworkFetcher(const std::shared_ptr<HelloCacheManager> &cache,
                                         const std::shared_ptr<HelloHttpRequest> &request,
                                         const std::shared_ptr<HelloRange> &range)
        : HelloDataFetcher(cache, request, range, "HelloNetworkFetcherVictor")
{
    logger.i("HelloNetworkFetcher::HelloNetworkFetcher(%p)", this);
}

HelloNetworkFetcher::~HelloNetworkFetcher()
{
    logger.i("HelloNetworkFetcher::~HelloNetworkFetcher(%p)", this);
}

bool HelloNetworkFetcher::run(const std::shared_ptr<HelloHttpRequest> &request)
{
    // 客户端连接句柄
    const int fd = request->getConnFd();
    const std::string &url = request->getRealUrl();

    logger.i("HelloNetworkFetcher::run start client fd[%d] url[%s]", fd, url.c_str());

    // 发起网络请求，获取数据
    // 阻塞式,下载资源
    HelloDownloader downloader;
    std::shared_ptr<HelloDownloader::HelloDownloadCtx> params
            = downloader.newParams(cache, request, range);

    bool partial = range->available(); // 是否请求部分资源?
    bool write2cache = request->isWrite2Cache(); // 是否需要写入本地缓存
    // 是否需要写入本地缓存
    if (write2cache)
    {
        std::string filename = "0"; // 默认全量请求,从0开始记录缓存
        if (partial)
        {
            filename = std::to_string(range->start); // 请求部分资源
        }
        const std::shared_ptr<HelloCacheInfo> &cacheInfo = cache->getCacheInfo(url);
        std::shared_ptr<HelloFile> file = cacheInfo->getCacheFile(filename);
        const std::string &filepath = file->getAbsolutFilepath();
        auto ofs = std::make_shared<std::ofstream>(filepath, std::ios::binary);
        if (!ofs->is_open())
        {
            logger.e("cannot open file[%s]", filename.c_str());
            return false;
        }
        params->ofs = ofs;
        logger.i("client[%d] prepare write to local cache[%s]", fd, filepath.c_str());
    }

    bool complete = downloader.download(params);
    std::string ret(complete ? "true" : "false");
    logger.i("HelloNetworkFetcher client[%d] complete[%s]", fd, ret.c_str());
    return complete;
}

